package com.scut.miaosha.controller;

import com.scut.miaosha.Result.CodeMsg;
import com.scut.miaosha.Result.Result;
import com.scut.miaosha.access.AccessLimit;
import com.scut.miaosha.domain.MiaoshaOrder;
import com.scut.miaosha.domain.MiaoshaUser;
import com.scut.miaosha.domain.OrderInfo;
import com.scut.miaosha.rabbitmq.MQSender;
import com.scut.miaosha.rabbitmq.MiaoshaMessage;
import com.scut.miaosha.redis.AccessKey;
import com.scut.miaosha.redis.GoodsKey;
import com.scut.miaosha.redis.MiaoshaKey;
import com.scut.miaosha.redis.RedisService;
import com.scut.miaosha.service.GoodsService;
import com.scut.miaosha.service.MiaoshaService;
import com.scut.miaosha.service.MiaoshaUserService;
import com.scut.miaosha.service.OrderService;
import com.scut.miaosha.vo.GoodsVo;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping(value = "/miaosha")
public class MiaoshaController implements InitializingBean {
    @Autowired
    MiaoshaUserService miaoshaUserService;

    @Autowired
    RedisService redisService;

    @Autowired
    GoodsService goodsService;

    @Autowired
    OrderService orderService;

    @Autowired
    MiaoshaService miaoshaService;

    @Autowired
    MQSender sender;

    private Map<Long,Boolean> localOverMap = new HashMap<>();


    /*
    系统初始化
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        List<GoodsVo> goodsList = goodsService.ListGoodsVo();
        if (goodsList == null) {
            return;
        }
        for (GoodsVo goodsVo : goodsList) {
            redisService.set(GoodsKey.getMiaoshaGoodsStock, "" + goodsVo.getId(), goodsVo.getStockCount());
            localOverMap.put(goodsVo.getId(),false);
        }

    }

    @RequestMapping(value = "/{path}/do_miaosha", method = RequestMethod.POST)
    @ResponseBody
    public Result<Integer> miaosha(Model model, MiaoshaUser user, @RequestParam("goodsId") long goodsId,@PathVariable("path") String path) {
        if (user == null) {
            return Result.error(CodeMsg.SESSION_ERROR);
        }
        //验证我们的path
        boolean check = miaoshaService.checkPath(user,goodsId,path);
        if(!check){
            return Result.error(CodeMsg.REQUEST_ILLGAL);
        }


        //内存标记，减少redis访问速度
        boolean over = localOverMap.get(goodsId);
        if(over)
        {
            return Result.error(CodeMsg.MIAO_SHA_OVER);
        }
        //判断是否repeat，redis.getKey(REPEAT+Userid+Goodsid)
        //如果存在直接 直接返回重复

        //预减库存
        //redis -1 为单线程 原子操作
        long stock = redisService.decr(GoodsKey.getMiaoshaGoodsStock, "" + goodsId);
        if (stock < 0) {
            localOverMap.put(goodsId,true);
            return Result.error(CodeMsg.MIAO_SHA_OVER);
        }
        //判断是否已经秒杀到
        MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdAndGoodsId(user.getId(),goodsId);
        if(order != null)
        {
            return Result.error(CodeMsg.REPEATE_MIAOSHA);
        }

        //入队
        MiaoshaMessage mm = new MiaoshaMessage();
        mm.setUser(user);
        mm.setGoodsId(goodsId);
        sender.sendMiaoshaMessage(mm);
        return Result.success(0);//排队中


//        model.addAttribute("user",user);
//        //判断商品还有没有库存
//        GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
//        int stock = goods.getStockCount();
//        if(stock <= 0)
//        {
//            model.addAttribute("errmsg", CodeMsg.MIAO_SHA_OVER.getMsg());
//            return Result.error(CodeMsg.MIAO_SHA_OVER);
//        }
//        //判断是否已经秒杀到了
//        MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdAndGoodsId(user.getId(),goodsId);
//        if(order != null)
//        {
//            model.addAttribute("errmsg", CodeMsg.REPEATE_MIAOSHA.getMsg());
//            return Result.error(CodeMsg.REPEATE_MIAOSHA);
//        }
//        //减库存 下订单 写入秒杀订单（需要在一个事物做）
//        OrderInfo orderInfo = null;
//        try {
//            orderInfo = miaoshaService.miaosha(user,goods);
//        }catch (Exception e){
//            return Result.error(CodeMsg.REPEATE_MIAOSHA);
//        }
//        model.addAttribute("goods",goods);
//        return Result.success(orderInfo);
//    }
    }

    /*
    秒杀成功：返回orderId
    -1 ： 库存不足
    0 ： 排队中
     */
    @RequestMapping(value = "/result", method = RequestMethod.GET)
    @ResponseBody
    public Result<Long> miaoshaResult(Model model, MiaoshaUser user, @RequestParam("goodsId") long goodsId) {
        if (user == null) {
            return Result.error(CodeMsg.SESSION_ERROR);
        }
        //成功返回的是orderId
        long result =  miaoshaService.getMiaoshaResult(user.getId(),goodsId);
        return Result.success(result);
    }


    @AccessLimit(seconds = 5 , maxCount = 5,needLogin = true)
    @RequestMapping(value = "/path", method = RequestMethod.GET)
    @ResponseBody
    public Result<String> getMiaoshaPath(HttpServletRequest request ,MiaoshaUser user, @RequestParam("goodsId") long goodsId , @RequestParam(value = "verifyCode" , defaultValue = "0") int verifyCode)  {
        if (user == null) {
            return Result.error(CodeMsg.SESSION_ERROR);
        }

        boolean check = miaoshaService.checkVerifyCode(user,goodsId,verifyCode);
        if(!check){
            return Result.error(CodeMsg.REQUEST_ILLGAL);
        }
        String path = miaoshaService.createMiaoshaPath(user,goodsId);

        return Result.success(path);
    }


    @RequestMapping(value = "/verifyCode" , method = RequestMethod.GET)
    @ResponseBody
    public Result<String> getMiaoshaVerifyCode(HttpServletResponse response,  MiaoshaUser user, @RequestParam("goodsId") long goodsId) {
        if (user == null) {
            return Result.error(CodeMsg.SESSION_ERROR);
        }
        try {
            BufferedImage image = miaoshaService.createVerifyCode(user,goodsId);
            OutputStream out = response.getOutputStream();
            ImageIO.write(image,"JPEG",out);
            out.flush();
            out.close();
            return null;
        }catch (Exception e){
            e.printStackTrace();
            return Result.error(CodeMsg.SESSION_ERROR);
        }
    }



}
